// 属性的形态
/**
     1.位置不同
        自有属性 Own Property
        原型链属性 Ptotype Property

     2.可见性不同
        可枚举属性 Enumerable
        不可枚举属性 Non-Enumerable

     3.字符串类型不同
        字符串属性 String key
        枚举属性 Symbol key
 */

/**
    for in 遍历自身以及原先脸上的可枚举的字符串属性
 */
Object.prototype.cc = 'cc'
var obj = {
    a: 1,
    b: 2
}
obj[Symbol['temp']] = '隐藏属性'

Object.defineProperty(obj, 'c', {
    value: 3,
    enumerable: false
})

for (let key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
        console.log(key)
    }
}
// 一般会配合着Object.prototype.hasOwnProperty最佳实现使用

/**
  Object.keys() 获取对象自身的可枚举的字符串属性
 */

/**
   Object.getOwnPropertyNames() 返回对象自身的全部字符串属性（包括不可枚举属性）
*/

/**
 *  Object.getOwnPropertySymbols 返回自身的全部Symbol属性
 * */


/**
 * Reflect.ownKeys() 返回对象自身所有的属性
 */

// 遍历顺序
/**
    自 ES6/ES2015 起，对象属性的遍历顺序遵循以下规则：

    数字键（Number-like keys）：
        按数值升序排列
        包括：正整数、负整数、浮点数（但实践中通常只使用正整数）

    字符串键（String keys）：
        按属性创建时间顺序排列（插入顺序）
        包括：普通字符串键、看起来像数字但不是数字的字符串（如 "01"）

    Symbol 键：
        按属性创建时间顺序排列（插入顺序）
 */
    const obj = {
        "2": "two",
        "foo": "bar",
        "01": "one",
        "1": "one",
        [Symbol("first")]: "first symbol",
        "baz": "qux",
        [Symbol("second")]: "second symbol",
        "0": "zero"
    };
    // 数字键会被优先排序
    console.log(Object.keys(obj)); 